﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;

using RaisingStudio.SmallProgram.Library.Internal;

namespace RaisingStudio.SmallProgram.Library
{
    [SmallProgramType]
    public static class File
    {
        public static Primitive LastError
        {
            get;
            set;
        }


        public static Primitive GetDirectories(Primitive directoryPath)
        {
            LastError = "";
#if SILVERLIGHT
            string directory = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) directoryPath);
#else
            string directory = Environment.ExpandEnvironmentVariables((string)directoryPath);
#endif
            try
            {
                if (Directory.Exists(directory))
                {
#if Monodevelop
					Dictionary<object, object> map = new Dictionary<object, object>();
#else
                    Dictionary<Primitive, Primitive> map = new Dictionary<Primitive, Primitive>();
#endif
                    int num = 1;
#if XBOX || Monodevelop
                    foreach (string subDirectory in Directory.GetDirectories((string)directoryPath))
#else
                    foreach (string subDirectory in Directory.EnumerateDirectories((string)directoryPath))
#endif
                    {
                        map[num] = subDirectory;
                        num++;
                    }
                    return Primitive.ConvertFromMap(map);
                }
                LastError = "Directory Path does not exist.";
                return "FAILED";
            }
            catch (Exception exception)
            {
                LastError = exception.Message;
                return "FAILED";
            }
        }

        public static Primitive GetFiles(Primitive directoryPath)
        {
            LastError = "";
#if SILVERLIGHT
            string directory = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) directoryPath);
#else
            string directory = Environment.ExpandEnvironmentVariables((string)directoryPath);
#endif
            try
            {
                if (Directory.Exists(directory))
                {
#if Monodevelop
					Dictionary<object, object> map = new Dictionary<object, object>();
#else
                    Dictionary<Primitive, Primitive> map = new Dictionary<Primitive, Primitive>();
#endif
                    int num = 1;
#if XBOX || Monodevelop
                    foreach (string file in Directory.GetFiles(directory))
#else
                    foreach (string file in Directory.EnumerateFiles(directory))
#endif
                    {
                        map[num] = file;
                        num++;
                    }
                    return Primitive.ConvertFromMap(map);
                }
                LastError = "Directory Path does not exist.";
                return "FAILED";
            }
            catch (Exception exception)
            {
                LastError = exception.Message;
                return "FAILED";
            }
        }


        public static Primitive GetSettingsFilePath()
        {
            return Path.ChangeExtension(SmallProgramApplication.GetEntryAssemblyPath(), ".settings");
        }

        public static Primitive GetTemporaryFilePath()
        {
            return Path.GetTempFileName();
        }


        public static Primitive CreateDirectory(Primitive directoryPath)
        {
            LastError = "";
#if SILVERLIGHT
            string directory = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) directoryPath);
#else
            string directory = Environment.ExpandEnvironmentVariables((string)directoryPath);
#endif
            try
            {
                Directory.CreateDirectory(directory);
                return "SUCCESS";
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                LastError = ex.Message;
            }
            return "FAILED";
        }

        public static Primitive DeleteDirectory(Primitive directoryPath)
        {
            LastError = "";
#if SILVERLIGHT
            string directory = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) directoryPath);
#else
            string directory = Environment.ExpandEnvironmentVariables((string)directoryPath);
#endif
            try
            {
                Directory.Delete(directory, true);
                return "SUCCESS";
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                LastError = ex.Message;
            }
            return "FAILED";
        }


        public static Primitive CopyFile(Primitive sourceFilePath, Primitive destinationFilePath)
        {
            LastError = "";
#if SILVERLIGHT
            string sourcePath = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) sourceFilePath);
            string destinationPath = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) destinationFilePath);
#else
            string sourcePath = Environment.ExpandEnvironmentVariables((string)sourceFilePath);
            string destinationPath = Environment.ExpandEnvironmentVariables((string)destinationFilePath);
#endif
            if (!System.IO.File.Exists(sourcePath))
            {
                LastError = "Source file doesn't exist.";
                return "FAILED";
            }
            if (Directory.Exists(destinationPath) || (destinationPath[destinationPath.Length - 1] == '\\'))
            {
                destinationPath = Path.Combine(destinationPath, Path.GetFileName(sourcePath));
            }
            try
            {
                string directoryName = Path.GetDirectoryName(destinationPath);
                if (!Directory.Exists(directoryName))
                {
                    Directory.CreateDirectory(directoryName);
                }
                System.IO.File.Copy(sourcePath, destinationPath, true);
                return "SUCCESS";
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                LastError = ex.Message;
            }
            return "FAILED";
        }

        public static Primitive DeleteFile(Primitive filePath)
        {
            LastError = "";
#if SILVERLIGHT
            string path = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) filePath);
#else
            string path = Environment.ExpandEnvironmentVariables((string)filePath);
#endif
            try
            {
                System.IO.File.Delete(path);
                return "SUCCESS";
            }
            catch (Exception exception)
            {
                Debug.WriteLine(exception.ToString());
                LastError = exception.Message;
            }
            return "FAILED";
        }


        public static Primitive ReadLine(Primitive filePath, Primitive lineNumber)
        {
            LastError = "";
#if SILVERLIGHT
            string path = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) filePath);
#else
            string path = Environment.ExpandEnvironmentVariables((string)filePath);
#endif
            if (lineNumber >= 0)
            {
                try
                {
                    if (!System.IO.File.Exists(path))
                    {
                        return "";
                    }
                    using (StreamReader reader = new StreamReader(path))
                    {
                        for (int i = 0; i < (lineNumber - 1); i++)
                        {
                            if (reader.ReadLine() == null)
                            {
                                return "";
                            }
                        }
                        return reader.ReadLine();
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.ToString());
                    LastError = ex.Message;
                }
            }
            return "";
        }

        public static Primitive ReadContents(Primitive filePath)
        {
            LastError = "";
#if SILVERLIGHT
            string path = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) filePath);
#else
            string path = Environment.ExpandEnvironmentVariables((string)filePath);
#endif
            try
            {
                if (!System.IO.File.Exists(path))
                {
                    return "";
                }
                using (StreamReader reader = new StreamReader(path))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                LastError = ex.Message;
            }
            return "";
        }

        public static Primitive WriteLine(Primitive filePath, Primitive lineNumber, Primitive contents)
        {
            LastError = "";
#if SILVERLIGHT
            string path = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) filePath);
#else
            string path = Environment.ExpandEnvironmentVariables((string)filePath);
#endif
            string tempFileName = Path.GetTempFileName();
            try
            {
                Primitive result;
                if (!System.IO.File.Exists(path))
                {
                    using (StreamWriter streamWriter = new StreamWriter(path))
                    {
                        streamWriter.WriteLine((string)contents);
                    }
                    result = "SUCCESS";
                    return result;
                }
                using (StreamWriter streamWriterTemp = new StreamWriter(tempFileName))
                {
                    using (StreamReader streamReader = new StreamReader(path))
                    {
                        int num = 1;
                        while (true)
                        {
                            string text = streamReader.ReadLine();
                            if (text == null)
                            {
                                break;
                            }
                            if (num == lineNumber)
                            {
                                streamWriterTemp.WriteLine((string)contents);
                            }
                            else
                            {
                                streamWriterTemp.WriteLine(text);
                            }
                            num++;
                        }
                        if (num <= lineNumber)
                        {
                            streamWriterTemp.WriteLine((string)contents);
                        }
                    }
                }
                System.IO.File.Copy(tempFileName, filePath, true);
                System.IO.File.Delete(tempFileName);
                result = "SUCCESS";
                return result;
            }
            catch (Exception ex)
            {
                LastError = ex.Message;
            }
            return "FAILED";
        }

        public static Primitive WriteContents(Primitive filePath, Primitive contents)
        {
            LastError = "";
#if SILVERLIGHT
            string path = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) filePath);
#else
            string path = Environment.ExpandEnvironmentVariables((string)filePath);
#endif
            try
            {
                using (StreamWriter streamWriter = new StreamWriter(path))
                {
                    streamWriter.Write((string)contents);
                    return "SUCCESS";
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                LastError = ex.Message;
            }
            return "FAILED";
        }


        public static Primitive InsertLine(Primitive filePath, Primitive lineNumber, Primitive contents)
        {
            LastError = "";
#if SILVERLIGHT
            string path = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) filePath);
#else
            string path = Environment.ExpandEnvironmentVariables((string)filePath);
#endif
            string tempFileName = Path.GetTempFileName();
            try
            {
                Primitive result;
                if (!System.IO.File.Exists(path))
                {
                    using (StreamWriter streamWriter = new StreamWriter(path))
                    {
                        streamWriter.WriteLine((string)contents);
                    }
                    result = "SUCCESS";
                    return result;
                }
                using (StreamWriter streamWriterTemp = new StreamWriter(tempFileName))
                {
                    using (StreamReader streamReader = new StreamReader(path))
                    {
                        int num = 1;
                        while (true)
                        {
                            string text = streamReader.ReadLine();
                            if (text == null)
                            {
                                break;
                            }
                            if (num == lineNumber)
                            {
                                streamWriterTemp.WriteLine((string)contents);
                            }
                            streamWriterTemp.WriteLine(text);
                            num++;
                        }
                        if (num <= lineNumber)
                        {
                            streamWriterTemp.WriteLine((string)contents);
                        }
                    }
                }
                System.IO.File.Copy(tempFileName, filePath, true);
                System.IO.File.Delete(tempFileName);
                result = "SUCCESS";
                return result;
            }
            catch (Exception ex)
            {
                LastError = ex.Message;
            }
            return "FAILED";
        }

        public static Primitive AppendContents(Primitive filePath, Primitive contents)
        {
            LastError = "";
#if SILVERLIGHT || XBOX
            string path = RaisingStudio.SmallProgram.Library.Environment.ExpandEnvironmentVariables((string) filePath);
#else
            string path = Environment.ExpandEnvironmentVariables((string)filePath);
#endif
            try
            {
                using (StreamWriter streamWriter = new StreamWriter(path, true))
                {
                    streamWriter.WriteLine((string)contents);
                }
                return "SUCCESS";
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                LastError = ex.Message;
            }
            return "FAILED";
        }
    }
}

